home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / mush5.7 / part11 < prev    next >
Encoding:
Internet Message Format  |  1987-09-19  |  53.5 KB

  1. Subject:  v11i061:  Mail user's shell, Part11/12
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: island!argv@Sun.COM (Dan Heller)
  7. Posting-number: Volume 11, Issue 61
  8. Archive-name: mush5.7/Part11
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 11 (of 12)."
  17. # Contents:  help.c main.c pick.c setopts.c signals.c
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'help.c' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'help.c'\"
  21. else
  22. echo shar: Extracting \"'help.c'\" \(9747 characters\)
  23. sed "s/^X//" >'help.c' <<'END_OF_FILE'
  24. X/* @(#)help.c    (c) copyright 10/15/86 (Dan Heller) */
  25. X
  26. X/*
  27. X * This file conatins two main routines:
  28. X *    display_help() and find_help()
  29. X * Both are virtually equivalent in functionality; they are passed
  30. X * a char * or a char **. If a char * is passed, then open "file"
  31. X * argument (containing help strings) and search for %str% and read
  32. X * the following text until %% or EOF into a local buffer.
  33. X * If str is a char **, then that array of strings is used directly.
  34. X *
  35. X * If display_help is used, then the final array of strings used is
  36. X * displayed in the center of the bitmapped console in a box with
  37. X * shading and the user must hit the left mouse button to remove the
  38. X * message.  the fd passed is the fd of the window locking the screen.
  39. X *
  40. X * In text mode, the routine find_help is used (or, if the graphics
  41. X * mode doesn't want to lock the screen to display a message). The
  42. X * same actions occur, but instead of "ifdef"ing up one function, I
  43. X * just made two for readability.
  44. X */
  45. X#include <stdio.h>
  46. X#include "strings.h"
  47. X
  48. X#define NULL_FILE (FILE *)0
  49. X
  50. X#ifdef SUNTOOL
  51. X#include <suntool/tool_hs.h>
  52. X#include <signal.h>
  53. X#include <suntool/fullscreen.h>
  54. X
  55. X#define l_width()      font->pf_defaultsize.x /* width of letter */
  56. X#define l_height()      font->pf_defaultsize.y /* height of letter */
  57. X
  58. X#define draw(win,x1,y1,x2,y2,OP)     pw_vector(win, x1,y1,x2,y2,OP,1)
  59. X#define box(win, x1,y1,x2,y2,OP) \
  60. X    draw(win,x1,y1, x1,y2, OP), \
  61. X    draw(win,x1,y2, x2,y2, OP), \
  62. X    draw(win,x2,y2, x2,y1, OP), \
  63. X    draw(win,x2,y1, x1,y1, OP)
  64. X
  65. X#define DEF_CONT_MSG    "Click LEFT mouse Button to continue."
  66. XDEFINE_CURSOR(oldcursor, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  67. X
  68. X/* shading */
  69. Xstatic short dat_shade_25[] = {
  70. X#include <images/square_25.pr>
  71. X};
  72. X
  73. Xstatic short dat_shade_50[] = {
  74. X#include <images/square_50.pr>
  75. X};
  76. X
  77. Xstatic short dat_shade_75[] = {
  78. X#include <images/square_75.pr>
  79. X};
  80. X
  81. Xstatic short dat_mouse_left[] = {
  82. X#include <images/confirm_left.pr> 
  83. X};
  84. X
  85. Xmpr_static(shade_25,        16, 16, 1, dat_shade_25);
  86. Xmpr_static(shade_50,        16, 16, 1, dat_shade_50);
  87. Xmpr_static(shade_75,        16, 16, 1, dat_shade_75);
  88. Xmpr_static(confirm_pr,      16, 16, 1, dat_mouse_left);
  89. X
  90. Xstatic struct cursor confirm_cursor = { 3, 3, PIX_SRC, &confirm_pr };
  91. Xstatic struct pixrect *shading;
  92. X
  93. X#else
  94. X
  95. X#include <sys/types.h>
  96. X#define wprint printf
  97. X#define print  printf
  98. X
  99. X#endif /* SUNTOOL */
  100. X
  101. X/* what to print if nothing was found */
  102. Xstatic char *def_msg[] = {
  103. X    "There is no help found for this item.",
  104. X    "Perhaps getting help from another item",
  105. X    "would be of some use.", 0
  106. X};
  107. X
  108. X#define MAXLINES    40
  109. X#define MAXLENGTH    128
  110. Xstatic FILE *help_file;
  111. Xstatic char file_name[128];
  112. X
  113. X#ifdef SUNTOOL
  114. Xdisplay_help(fd, str, file, font)
  115. Xregister caddr_t *str;   /* could be a single or double pointer */
  116. Xregister char *file;
  117. Xregister struct pixfont *font;
  118. X{
  119. X    struct fullscreen *fs;
  120. X    struct inputmask im, old_im;
  121. X    struct inputevent event;
  122. X    struct rect rect;
  123. X    register char *p;
  124. X    register int x, y, z, height;
  125. X    struct pixrect *saved, *save_bits();
  126. X    int width = 0, old_link;
  127. X    char *cont_msg = DEF_CONT_MSG, *getenv();
  128. X    char args[MAXLINES][MAXLENGTH], help_str[40];
  129. X
  130. X    if (!shading)
  131. X    if (p = getenv("SHADE")) {
  132. X        register int x = atoi(p);
  133. X        if (x <= 25)
  134. X        shading = &shade_25;
  135. X        else if (x <= 50)
  136. X        shading = &shade_50;
  137. X        else
  138. X        shading = &shade_75;
  139. X    } else
  140. X        shading = &shade_25;
  141. X
  142. X    /* If no file given, take "str" arg as message to print */
  143. X    if (!file || !*file) {
  144. X    file = NULL;
  145. X    for(height = 0; *str && height < MAXLINES-1; height++) {
  146. X        if (!compose_str(*str, &width))
  147. X        break;
  148. X        (void) strcpy(args[height], *str++);
  149. X    }
  150. X    } else {
  151. X    if (!*file_name || strcmp(file_name, file)) {
  152. X        (void) strcpy(file_name, file);
  153. X        if (help_file)
  154. X        fclose(help_file), help_file = NULL_FILE;
  155. X    }
  156. X    /* file remains open */
  157. X    if (!help_file && !(help_file = fopen(file_name, "r")))
  158. X        return -1;
  159. X    /* look for %str% in helpfile */
  160. X    (void) sprintf(help_str, "%%%s%%\n", str);
  161. X
  162. X    rewind(help_file);
  163. X
  164. X    while(p = fgets(args[0], MAXLENGTH, help_file))
  165. X        if (*p == '%' && !strcmp(p, help_str))
  166. X        break;
  167. X
  168. X    if (!p || !fgets(args[0], MAXLENGTH, help_file))
  169. X        for(height = 0; def_msg[height] && height < MAXLINES-1; height++) {
  170. X        compose_str(def_msg[height], &width);
  171. X        (void) strcpy(args[height], def_msg[height]);
  172. X        }
  173. X    else for (height = 0; p && *p && strcmp(p, "%%\n"); height++) {
  174. X        compose_str(p, &width);
  175. X        p = fgets(args[height+1], MAXLENGTH, help_file);
  176. X        }
  177. X    }
  178. X    if (height == MAXLINES - 1)
  179. X    print("Help message is too long!\n");
  180. X
  181. X    fs = fullscreen_init(fd);
  182. X    /* Figure out the height and width in pixels (rect.r_height, rect.r_width)
  183. X     * Remember to provide for the "confirm" line (cont_msg).
  184. X     * extend the new box by 15 pixels on the sides (30 total), top, and bottom.
  185. X     * finally, add 16 pixels for "shadow" -- remove before clearing area
  186. X     * to preserve background and give a shadow-like appearance.
  187. X     */
  188. X    if ((x = strlen(cont_msg)) > width)
  189. X    width = x; /* this x value must be saved! */
  190. X    rect.r_width = (width*l_width()) + 30 + 16;
  191. X    rect.r_height = ((height+1) * l_height()) + 30 + 16;
  192. X    rect.r_left = fs->fs_screenrect.r_left +
  193. X    (fs->fs_screenrect.r_width / 2) - (rect.r_width / 2);
  194. X    rect.r_top = fs->fs_screenrect.r_top +
  195. X    (fs->fs_screenrect.r_height / 2) - (rect.r_height / 2);
  196. X
  197. X    /* save old area */
  198. X    saved = save_bits(fs->fs_pixwin, &rect);
  199. X
  200. X    /* prepare surface, clear the background, and reset rect for shadow */
  201. X    pw_preparesurface(fs->fs_pixwin, &rect);
  202. X    pw_lock(fs->fs_pixwin, &rect);
  203. X    rect.r_width -= 16;
  204. X    rect.r_height -= 16;
  205. X
  206. X    pw_writebackground(fs->fs_pixwin,
  207. X    rect.r_left, rect.r_top, rect.r_width, rect.r_height, PIX_CLR);
  208. X
  209. X    /* make a box that's 5 pixels thick. Then add a thin box inside it */
  210. X    for (z = 0; z < 5; z++)
  211. X    box(fs->fs_pixwin,
  212. X        rect.r_left+z, rect.r_top+z,
  213. X        rect.r_left+rect.r_width-z-1, rect.r_top+rect.r_height-z-1,
  214. X        PIX_SRC);
  215. X    box(fs->fs_pixwin,
  216. X    rect.r_left+z+2, rect.r_top+z+2,
  217. X    rect.r_left+rect.r_width-z-3, rect.r_top+rect.r_height-z-3,
  218. X    PIX_SRC);
  219. X
  220. X    /* shading -- pw_replrop() doesn't work (bug)
  221. X     * NOTE: fs->fs_screenrect.r_top and r_left are negative values
  222. X     */
  223. X    pr_replrop(fs->fs_pixwin->pw_pixrect,
  224. X       rect.r_left + rect.r_width - fs->fs_screenrect.r_left,
  225. X       rect.r_top + 16 - fs->fs_screenrect.r_top,
  226. X       16, rect.r_height-16, PIX_SRC|PIX_DST, shading, 0, 0);
  227. X    pr_replrop(fs->fs_pixwin->pw_pixrect,
  228. X       rect.r_left + 16 - fs->fs_screenrect.r_left,
  229. X       rect.r_top+rect.r_height - fs->fs_screenrect.r_top,
  230. X       rect.r_width, 16, PIX_SRC|PIX_DST, shading, 0, 0);
  231. X
  232. X    if (x > width)
  233. X    x = 15;
  234. X    else
  235. X    x = rect.r_width/2 - (x*l_width())/2;
  236. X    y = rect.r_height - 15;
  237. X
  238. X    /* Print everything in reverse order now; start with the "confirm" string
  239. X     * (which is centered and highlighted)
  240. X     */
  241. X    pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y, PIX_SRC,font, cont_msg);
  242. X    pw_text(fs->fs_pixwin, rect.r_left+x+1, rect.r_top+y, PIX_SRC|PIX_DST, font,
  243. X        cont_msg);
  244. X
  245. X    y -= (5 + l_height());
  246. X    x = 15;
  247. X
  248. X    /* now print each string in reverse order (start at bottom of box) */
  249. X    for (height--; height >= 0; height--) {
  250. X    pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y,
  251. X        PIX_SRC, font, args[height]);
  252. X    y -= l_height();
  253. X    }
  254. X
  255. X    pw_unlock(fs->fs_pixwin);
  256. X
  257. X    /* wait for user to read and confirm */
  258. X    win_getinputmask(fd, &old_im, &old_link);
  259. X    input_imnull(&im);
  260. X    im.im_flags |= IM_ASCII;
  261. X    win_setinputcodebit(&im, MS_LEFT);
  262. X    win_setinputcodebit(&im, MS_MIDDLE);
  263. X    win_setinputcodebit(&im, MS_RIGHT);
  264. X    win_setinputmask(fd, &im, &im, WIN_NULLLINK);
  265. X    win_getcursor(fd, &oldcursor);
  266. X    win_setcursor(fd, &confirm_cursor);
  267. X    while (input_readevent(fd, &event) != -1 && event.ie_code != MS_LEFT);
  268. X
  269. X    /* restore old cursor */
  270. X    win_setcursor(fd, &oldcursor);
  271. X
  272. X    /* restore old pixrect (size already restored) */
  273. X    rect.r_height += 16; /* to take care of the shadow */
  274. X    rect.r_width += 16;
  275. X    restore_bits(fs->fs_pixwin, &rect, saved);
  276. X    /* release screen */
  277. X    fullscreen_destroy(fs);
  278. X    win_setinputmask(fd, &old_im, &old_im, old_link);
  279. X    return 0;
  280. X}
  281. X
  282. Xstatic
  283. Xcompose_str(p, width)
  284. Xregister char *p;
  285. Xint *width;
  286. X{
  287. X    register int x;
  288. X    if (!p || !*p)
  289. X    return 0;
  290. X    x = strlen(p);
  291. X    if (p[x-1] == '\n')
  292. X    p[--x] = 0; /* get rid of newline */
  293. X    if (x > *width)
  294. X    *width = x;
  295. X    return 1;
  296. X}
  297. X#endif SUNTOOL
  298. X
  299. Xfind_help(str, file)
  300. Xregister caddr_t *str;
  301. Xregister char *file;
  302. X{
  303. X    register char    *p;
  304. X    char        args[MAXLINES][MAXLENGTH], help_str[40];
  305. X    register int    n, height;
  306. X    extern char        *no_newln();
  307. X
  308. X    /* If no file given, take "str" arg as message to print */
  309. X    if (!file || !*file) {
  310. X    file = NULL;
  311. X    for(height = 0; *str && height < MAXLINES-1; height++)
  312. X        (void) strcpy(args[height], *str++);
  313. X    } else {
  314. X    if (!*file_name || strcmp(file_name, file)) {
  315. X        (void) strcpy(file_name, file);
  316. X        if (help_file)
  317. X        fclose(help_file), help_file = NULL_FILE;
  318. X    }
  319. X    /* file remains open */
  320. X    if (!help_file && !(help_file = fopen(file_name, "r")))
  321. X        return -1;
  322. X    /* look for %str% in helpfile */
  323. X    (void) sprintf(help_str, "%%%s%%\n", str);
  324. X    rewind(help_file);
  325. X    while(p = fgets(args[0], MAXLENGTH, help_file))
  326. X        if (*p == '%' && !strcmp(p, help_str))
  327. X        break;
  328. X    if (!p || !fgets(args[0], MAXLENGTH, help_file))
  329. X        for(height = 0; def_msg[height] && height < MAXLINES-1; height++)
  330. X        (void) strcpy(args[height], def_msg[height]);
  331. X    else for (height = 0; p && *p && strcmp(p, "%%\n"); height++)
  332. X        p = fgets(args[height+1], MAXLENGTH, help_file);
  333. X    }
  334. X    if (height == MAXLINES - 1)
  335. X    print("Help message is too long!\n");
  336. X
  337. X    for (n = 0; n < height; n++) {
  338. X    (void) no_newln(args[n]);
  339. X    wprint("%s\n", args[n]);
  340. X    }
  341. X
  342. X    return 0;
  343. X}
  344. END_OF_FILE
  345. if test 9747 -ne `wc -c <'help.c'`; then
  346.     echo shar: \"'help.c'\" unpacked with wrong size!
  347. fi
  348. # end of 'help.c'
  349. fi
  350. if test -f 'main.c' -a "${1}" != "-c" ; then 
  351.   echo shar: Will not clobber existing file \"'main.c'\"
  352. else
  353. echo shar: Extracting \"'main.c'\" \(10552 characters\)
  354. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  355. X/* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  356. X
  357. X#include "mush.h"
  358. X
  359. Xstatic char *usage_str =
  360. X#ifdef SUNTOOL 
  361. X    "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-t] [-s subject] [users]\n";
  362. X#else
  363. X#ifdef CURSES
  364. X    "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  365. X#else
  366. X    "usage: %s [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  367. X#endif CURSES
  368. X#endif SUNTOOL
  369. X
  370. X#if defined(sun) && defined(M_DEBUG)
  371. Xcpu()
  372. X{
  373. X    print("CPU time limit exceeded!\n");
  374. X}
  375. X#endif sun && DEBUG
  376. X
  377. X/*ARGSUSED*/   /* we ignore envp */
  378. Xmain(argc, argv)
  379. Xchar **argv;
  380. X{
  381. X    int         flg = NO_FLG, n;
  382. X    char         f_flags[10], buf[256], *Cc = NULL;
  383. X    register char   *p;
  384. X
  385. X    if (prog_name = rindex(*argv, '/'))
  386. X    prog_name++;
  387. X    else
  388. X    prog_name = *argv;
  389. X
  390. X    (void) signal(SIGBUS,  bus_n_seg);
  391. X    (void) signal(SIGSEGV, bus_n_seg);
  392. X
  393. X    f_flags[0] = 0;
  394. X    mailfile = "";
  395. X
  396. X#if defined(sun) && defined(M_DEBUG)
  397. X    (void) signal(SIGXCPU, cpu);
  398. X
  399. X    if (p = getenv("MALLOC_DEBUG"))
  400. X    malloc_debug(atoi(p));
  401. X    else
  402. X    malloc_debug(0);
  403. X#endif sun && debug
  404. X
  405. X    if (!isatty(0))
  406. X    turnon(glob_flags, REDIRECT);
  407. X    f_flags[0] = '\0';
  408. X
  409. X    n = 0; /* don't ignore no such file or directory */
  410. X    p = getpath(COMMAND_HELP, &n);
  411. X    if (n) {
  412. X    fprintf(stderr, "Warning: can't read %s: %s\n", COMMAND_HELP, p);
  413. X    cmd_help = "cmd_help";
  414. X    } else
  415. X    strdup(cmd_help, p);
  416. X#ifdef SUNTOOL
  417. X    n = 0;
  418. X    p = getpath(TOOL_HELP, &n);
  419. X    if (n) {
  420. X    fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p);
  421. X    tool_help = "tool_help";
  422. X    } else
  423. X    strdup(tool_help, p);
  424. X
  425. X    istool = strlen(prog_name) > 3 &&
  426. X          !strcmp(prog_name+strlen(prog_name)-4, "tool");
  427. X    time_out = 60;
  428. X#endif SUNTOOL
  429. X
  430. X    /*
  431. X     * preparse the command line looking for certain arguments which must
  432. X     * be known before sourcing the .mushrc file.  This should definitely
  433. X     * be optimized -- see the TODO file accompanying this distibution.
  434. X     */
  435. X    n = 1;
  436. X    if (argc > 1) {
  437. X    char **args;
  438. X    for (args = argv; *args; args++)
  439. X#ifdef SUNTOOL
  440. X        if (!strcmp(*args, "-t"))
  441. X        istool = 1;
  442. X        else
  443. X#endif SUNTOOL
  444. X        if (!strcmp(*args, "-C") && !hdrs_only)
  445. X        /* this will only temporarily be turned on! */
  446. X        turnon(glob_flags, PRE_CURSES);
  447. X        /* headers only?  get args later, just set to a non-null value */
  448. X        else if (!strncmp(*args, "-H", 2))
  449. X        hdrs_only = NO_STRING, turnoff(glob_flags, PRE_CURSES);
  450. X        else if (!strcmp(*args, "-d"))
  451. X        debug = 1;
  452. X        else if (!strcmp(*args, "-n"))
  453. X        n = 0;
  454. X    }
  455. X
  456. X    /*
  457. X     * read mailrc and so forth. Global variables not set there will have
  458. X     * default settings here.  Set them first so user overrides in "source()"
  459. X     */
  460. X    init(); /* must be done before checking mail since "login" is set here */
  461. X
  462. X    /* check to see if we have any mail at all */
  463. X    if (argc < 2 && !istool) { /* istool may be set with one arg: "mushtool" */
  464. X    struct stat statb;
  465. X    if (stat(sprintf(buf, "%s/%s", MAILDIR, login), &statb) ||
  466. X        statb.st_size == 0) {
  467. X        printf("No mail for %s.\n", login);
  468. X        exit(1);
  469. X    }
  470. X    }
  471. X    /* -n flag above */
  472. X    if (n)
  473. X    (void) source(0, DUBL_NULL);
  474. X
  475. X#ifdef SUNTOOL
  476. X    if (istool)
  477. X    if (ison(glob_flags, REDIRECT))
  478. X        puts("You can't redirect input to a tool."), exit(1);
  479. X    else
  480. X        make_tool(argc, argv), turnon(glob_flags, DO_SHELL);
  481. X#endif SUNTOOL
  482. X
  483. X    for (argv++; *argv && **argv == '-'; argv++)
  484. X    switch (argv[0][1]) {
  485. X        case 'e':
  486. X        /*
  487. X         * don't set tty modes -- e.g. echo and cbreak modes aren't
  488. X         * changed.
  489. X         */
  490. X        turnon(glob_flags, ECHO_FLAG);
  491. X#ifdef CURSES
  492. X        when 'C':
  493. X        /* don't init curses -- don't even set iscurses.   */
  494. X        if (istool) {
  495. X            puts("-C: You are already running in tool mode");
  496. X            turnoff(glob_flags, PRE_CURSES);
  497. X        } else if (hdrs_only) {
  498. X            puts("headers only: ignoring -C flag");
  499. X            turnoff(glob_flags, PRE_CURSES);
  500. X        } else
  501. X            turnon(glob_flags, PRE_CURSES);
  502. X#endif CURSES
  503. X        when 'N':
  504. X        (void) strcat(f_flags, "-N ");
  505. X        when 'r':
  506. X        (void) strcat(f_flags, "-r "); /* folder() argument */
  507. X        when 'H':
  508. X        if (istool) {
  509. X            puts("running in tool-mode; -H option ignored.");
  510. X            break;
  511. X        }
  512. X        turnoff(glob_flags, PRE_CURSES);
  513. X        if (*(hdrs_only = (*argv)+2) != ':')
  514. X            hdrs_only = ":a";
  515. X        (void) strcat(f_flags, "-N "); /* tell folder not to do_hdrs */
  516. X        when 'i':
  517. X        /* force interactive even if !isatty(0) */
  518. X        turnoff(glob_flags, REDIRECT);
  519. X        /* if no argument for this, use mbox in _current directory_ */
  520. X        when 'f':
  521. X        if (argv[1])
  522. X            p = *++argv;
  523. X        else if (!(p = do_set(set_options, "mbox")) || !*p)
  524. X            p = DEF_MBOX;
  525. X        strdup(mailfile, getpath(p, &n));
  526. X        if (n) {
  527. X            if (n == -1)
  528. X            print("%s: %s\n", p, mailfile);
  529. X            else
  530. X            print("%s: Is a directory\n", mailfile);
  531. X            if (!istool)
  532. X            exit(1);
  533. X            strdup(mailfile, "");
  534. X        }
  535. X        when '1':
  536. X        if (argv[1])
  537. X            strdup(cmd_help, *++argv);
  538. X        else
  539. X            puts("-1 \"filename\""), cleanup(0);
  540. X#ifdef SUNTOOL
  541. X        when '2':
  542. X        if (argv[1])
  543. X            strdup(tool_help, *++argv);
  544. X        else
  545. X            puts("-2 \"filename\""), cleanup(0);
  546. X#endif SUNTOOL
  547. X        when 's':
  548. X        if (istool)
  549. X            puts("bad option when run as a tool");
  550. X        else if (argv[1])
  551. X            (void) strcpy(buf, *++argv);
  552. X        else
  553. X            puts("-s \"subject\""), cleanup(0);
  554. X        when 'c':
  555. X        if (istool)
  556. X            puts("bad option when run as a tool");
  557. X        else if (argv[1])
  558. X            strdup(Cc, *++argv);
  559. X        else
  560. X            puts("-c \"cc list\""), exit(1);
  561. X        when 'S': turnon(glob_flags, DO_SHELL); /* force the shell */
  562. X#ifdef VERBOSE_ARG
  563. X        when 'v':
  564. X        if (istool)
  565. X            puts("bad option when run as a tool");
  566. X        turnon(flg, VERBOSE);
  567. X#endif VERBOSE_ARG
  568. X#ifdef SUNTOOL
  569. X            when 'T':
  570. X        if (!*++argv)
  571. X            continue;
  572. X        if (istool && (time_out = atoi(*argv)) <= 29)
  573. X            time_out = 30;
  574. X        else
  575. X            printf("-T flag ignored unless run as tool."), exit(1);
  576. X        when 't': ;   /* prevent error message */
  577. X#endif SUNTOOL
  578. X        when 'n': case 'd': ;   /* prevent error messages */
  579. X        otherwise:
  580. X        print("%s: unknown option: `%c'\n", prog_name,
  581. X            argv[0][1]? argv[0][1] : '-');
  582. X        print(usage_str, prog_name);
  583. X        if (!istool)
  584. X            exit(1);
  585. X    }
  586. X
  587. X    /* now we're ready for I/O */
  588. X    if (isoff(glob_flags, REDIRECT)) {
  589. X    /* make sure we can always recover from no echo mode */
  590. X    (void) signal(SIGINT, catch);
  591. X    (void) signal(SIGQUIT, catch);
  592. X    if (istool)
  593. X        turnon(glob_flags, ECHO_FLAG);
  594. X    savetty();
  595. X#ifdef TIOCGLTC
  596. X    if (isatty(0) && ioctl(0, TIOCGLTC, <chars))
  597. X        error("TIOCGLTC");
  598. X#endif TIOCGLTC
  599. X#ifdef SIGCONT
  600. X    (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  601. X#endif SIGCONT
  602. X    /* echo_off() checks to see if echo_flg is set, so don't worry */
  603. X    echo_off();
  604. X    }
  605. X
  606. X    if (*argv) {
  607. X    char recipients[BUFSIZ];
  608. X    if (*mailfile)
  609. X        puts("You can't specify more than one folder"), cleanup(0);
  610. X    if (istool)
  611. X        puts("You can't mail someone and run a tool."), cleanup(0);
  612. X    (void) argv_to_string(recipients, argv);
  613. X    /* prompt for subject and Cc list, but not "To: "
  614. X     * mail_someone() already takes care of redirection.
  615. X     * if -s or -c options are given, they will be passed.
  616. X     */
  617. X    if (do_set(set_options, "autosign"))
  618. X        turnon(flg, SIGN);
  619. X    if (do_set(set_options, "autoedit"))
  620. X        turnon(flg, EDIT);
  621. X    if (do_set(set_options, "verbose"))
  622. X        turnon(flg, VERBOSE);
  623. X    if (do_set(set_options, "fortune")) {
  624. X        p = do_set(set_options, "fortunates");
  625. X        if (!p || *p && (chk_two_lists(recipients, p, " \t,")
  626. X           || (Cc && *Cc && chk_two_lists(Cc, p, " \t,"))))
  627. X        turnon(flg, DO_FORTUNE);
  628. X    }
  629. X    /* set now in case user is not running shell, but is running debug */
  630. X    (void) signal(SIGCHLD, sigchldcatcher);
  631. X    (void) mail_someone(recipients, buf, Cc, flg, NULL);
  632. X    /* do shell set from above: "mush -S user" perhaps */
  633. X    if (isoff(glob_flags, DO_SHELL)) {
  634. X        if (isoff(glob_flags, REDIRECT))
  635. X        echo_on();
  636. X        exit(0);
  637. X    }
  638. X    }
  639. X    if (ison(glob_flags, REDIRECT)) {
  640. X    puts("You can't redirect input unless you're sending mail.");
  641. X    puts("If you want to run a shell with redirection, use \"-i\"");
  642. X    cleanup(0);
  643. X    }
  644. X    if (!*mailfile) {
  645. X    strdup(mailfile, sprintf(buf, "%s/%s", MAILDIR, login));
  646. X    if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  647. X        /* we know it's not the spool file here */
  648. X        printf("No mail in %s.\n", mailfile);
  649. X        echo_on(), exit(0);
  650. X    }
  651. X    }
  652. X    /* At this point, we know we're running a shell, so... */
  653. X    if (!hdrs_only) {
  654. X    /* catch will test DO_SHELL and try to longjmp if set.  this is a
  655. X     * transition state from no-shell to do-shell to ignore sigs to
  656. X     * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  657. X     */
  658. X    turnon(glob_flags, DO_SHELL);
  659. X    turnon(glob_flags, IGN_SIGS);
  660. X#ifdef CURSES
  661. X    if (ison(glob_flags, PRE_CURSES))
  662. X        (void) curses_init(0, DUBL_NULL);
  663. X    turnoff(glob_flags, PRE_CURSES);
  664. X#endif CURSES
  665. X    }
  666. X
  667. X    /* find a free tmpfile */
  668. X    flg = getpid();
  669. X    if (!(p = do_set(set_options, "home")) || !*p)
  670. X    p = ALTERNATE_HOME;
  671. X    while (!access(sprintf(tempfile, "%s/.%s%d", p, prog_name, flg++), 0))
  672. X    ;
  673. X    /* just create the file, make sure it's empty.  It'll close later and
  674. X     * be reopened for reading only.
  675. X     */
  676. X    {
  677. X    int omask = umask(077);
  678. X    if (!(tmpf = fopen(tempfile, "w"))) {
  679. X        error("Can't create tempfile %s", tempfile);
  680. X        cleanup(0);
  681. X    }
  682. X    (void) umask(omask);
  683. X    }
  684. X
  685. X    /* do pseudo-intelligent stuff with certain signals */
  686. X    (void) signal(SIGINT,  catch);
  687. X    (void) signal(SIGQUIT, catch);
  688. X    (void) signal(SIGHUP,  catch);
  689. X
  690. X    /* if we're a suntool, then state the version and mark first message
  691. X     * as "read" since it will be displayed right away
  692. X     */
  693. X    if (!hdrs_only && !istool && !do_set(set_options, "quiet"))
  694. X    printf("%s: Type '?' for help.\n", VERSION);
  695. X
  696. X    (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
  697. X    if (argv = make_command(buf, TRPL_NULL, &argc)) {
  698. X    (void) folder(argc, argv, NULL);
  699. X    free_vec(argv);
  700. X    }
  701. X
  702. X    if (hdrs_only) {
  703. X    (void) sprintf(buf, "headers %s", hdrs_only);
  704. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  705. X        (void) do_hdrs(argc, argv, NULL);
  706. X    cleanup(0);
  707. X    }
  708. X
  709. X    if (istool && msg_cnt)
  710. X    set_isread(current_msg);
  711. X
  712. X    sort_commands();
  713. X    sort_variables();
  714. X
  715. X#ifdef SUNTOOL
  716. X    if (istool) {
  717. X    turnoff(glob_flags, IGN_SIGS);
  718. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  719. X    timerclear(&(mail_timer.it_interval));
  720. X    timerclear(&(mail_timer.it_value));
  721. X    mail_timer.it_value.tv_sec = time_out;
  722. X    setitimer(ITIMER_REAL, &mail_timer, NULL);
  723. X    (void) signal(SIGALRM, check_new_mail);
  724. X    unlock_cursors();
  725. X    while (!(tool->tl_flags & TOOL_DONE))
  726. X        tool_select(tool, 1);
  727. X    cleanup(0);
  728. X    }
  729. X#endif SUNTOOL
  730. X    do_loop();
  731. X}
  732. X
  733. Xdo_version()
  734. X{
  735. X    print("%s\n", VERSION);
  736. X    return -1;
  737. X}
  738. END_OF_FILE
  739. if test 10552 -ne `wc -c <'main.c'`; then
  740.     echo shar: \"'main.c'\" unpacked with wrong size!
  741. fi
  742. # end of 'main.c'
  743. fi
  744. if test -f 'pick.c' -a "${1}" != "-c" ; then 
  745.   echo shar: Will not clobber existing file \"'pick.c'\"
  746. else
  747. echo shar: Extracting \"'pick.c'\" \(10068 characters\)
  748. sed "s/^X//" >'pick.c' <<'END_OF_FILE'
  749. X/* @(#)pick.c    2.4    (c) copyright 10/18/86 (Dan Heller) */
  750. X
  751. X#include "mush.h"
  752. X
  753. Xstatic int before, mdy[3], search_from, search_subj, search_to, xflg, icase;
  754. X
  755. Xdo_pick(n, argv, list)
  756. Xregister int n;
  757. Xregister char **argv, list[];
  758. X{
  759. X    if (n > 1 && !strcmp(argv[1], "-?"))
  760. X    return help(0, "pick", cmd_help);
  761. X
  762. X    /* if is_pipe, then the messages to search for are already set.
  763. X     * if not piped, then reverse the bits for all message numbers.
  764. X     * That is, search EACH message. only those matching will be returned.
  765. X     */
  766. X    if (isoff(glob_flags, IS_PIPE))
  767. X    bitput(list, list, msg_cnt, =~) /* macro, turn on all bits */
  768. X    if (pick(n, argv, list, isoff(glob_flags, DO_PIPE)) == -1)
  769. X    return -1;
  770. X    if (isoff(glob_flags, DO_PIPE)) {
  771. X    if (istool)
  772. X        print("Messages: ");
  773. X    for (n = 0; n < msg_cnt; n++)
  774. X        if (msg_bit(list, n))
  775. X        if (istool)
  776. X            print_more("%d ", n+1);
  777. X        else
  778. X            print("%s\n", compose_hdr(n));
  779. X    }
  780. X    return 0;
  781. X}
  782. X
  783. Xpick(ret, argv, list, verbose)
  784. Xregister int ret;
  785. Xregister char **argv, list[];
  786. X{
  787. X    register char c;
  788. X    int o_before = before, o_mdy[3], o_search_from = search_from,
  789. X    o_search_subj = search_subj, o_search_to = search_to, o_xflg = xflg, n;
  790. X    for (c = 0; c < 3; c++)
  791. X    o_mdy[c] = mdy[c];
  792. X
  793. X    ret = -1;
  794. X    if (!msg_cnt) {
  795. X    print("No Messages.\n");
  796. X    goto bad;
  797. X    }
  798. X
  799. X    icase = before = mdy[0] = search_from = search_subj = xflg = 0;
  800. X    while (*argv && *++argv && **argv == '-')
  801. X    switch(c = argv[0][1]) {
  802. X        /* users specifies a range */
  803. X        case 'r': {
  804. X        int X = 2;
  805. X        /* if not a pipe, then clear all bits cuz we only want
  806. X         * to search the message specified here...
  807. X         * If it is a pipe, then add to the messages searched for.
  808. X         */
  809. X        if (isoff(glob_flags, IS_PIPE))
  810. X            clear_msg_list(list);
  811. X        /*  "-r10-15"
  812. X         *     ^argv[1][2]  if NULL, then
  813. X         * list detached from "r" e.g. "-r" "5-20"
  814. X         */
  815. X        if (!argv[0][X])
  816. X            argv++, X = 0;
  817. X        (*argv) += X;
  818. X        n = get_msg_list(argv, list);
  819. X        (*argv) -= X;
  820. X        if (n == -1)
  821. X            goto bad;
  822. X        argv += (n-1); /* we're going to increment another up top */
  823. X        }
  824. X        when 'd':
  825. X        if (!*++argv) {
  826. X            print("specify a date for -%c\n", c);
  827. X            goto bad;
  828. X        }
  829. X        if (!date1(*argv))
  830. X            goto bad;
  831. X        when 's' : case 'f': case 't':
  832. X        if (search_subj + search_from + search_to > 1) {
  833. X            print("specify one of `s', `f' or `t' only\n");
  834. X            goto bad;
  835. X            }
  836. X            if (c == 's')
  837. X            search_subj = 1;
  838. X        else if (c == 'f')
  839. X            search_from = 1;
  840. X        else
  841. X            search_to = 1;
  842. X        when 'x' : xflg = 1;
  843. X        when 'i' : icase = 1;
  844. X        otherwise:
  845. X        print("pick: unknown flag: %c\n", argv[0][1]);
  846. X        clear_msg_list(list);
  847. X        return -1;
  848. X    }
  849. X    if (verbose) {
  850. X    print_more("Searching for messages");
  851. X    if (mdy[1] == 0)
  852. X        print(" that %s \"%s\"", (xflg)? "doesn't contain": "contains",
  853. X                (*argv)? *argv: "<previous expression>");
  854. X    if (search_subj)
  855. X        print_more(" in subject line");
  856. X    else if (search_from)
  857. X        print_more(" from author names");
  858. X    else if (search_to)
  859. X        print_more(" from the To: field");
  860. X    if (mdy[1] > 0) {
  861. X        extern char *month_names[]; /* from dates.c */
  862. X        print_more(" dated on or %s %s. %d, 19%d.",
  863. X          (before)? "before": "after",
  864. X          month_names[mdy[0]], mdy[1], mdy[2]);
  865. X    }
  866. X    print_more("\n");
  867. X    }
  868. X    if (mdy[1] > 0 && icase)
  869. X    print("using date: -i flag ignored.\n");
  870. X    ret = find_pattern(*argv, list);
  871. Xbad:
  872. X    before = o_before, search_from = o_search_from,
  873. X    search_subj = o_search_subj, search_to = o_search_to, xflg = o_xflg;
  874. X    for (c = 0; c < 3; c++)
  875. X    mdy[c] = o_mdy[c];
  876. X    return ret;
  877. X}
  878. X
  879. Xfind_pattern(p, list)
  880. Xregister char *p, list[];
  881. X{
  882. X    register int n, val, i; /* val is return value from regex or re_exec */
  883. X    long bytes = 0;
  884. X    char buf[BUFSIZ];
  885. X    static char *err = (char *)-1;
  886. X#ifndef SYSV
  887. X    char *re_comp();
  888. X#else
  889. X    char *regcmp(), *regex();
  890. X#endif SYSV
  891. X
  892. X    if (p && *p == '\\')
  893. X    p++;  /* take care of escaping special cases (`-', `\') */
  894. X
  895. X    /* specify what we're looking for */
  896. X    if (p && *p) {
  897. X    if (icase)
  898. X        p = lcase_strcpy(buf, p);
  899. X#ifndef SYSV
  900. X    if (err = re_comp(p)) {
  901. X        print("re_comp error: %s\n", err);
  902. X        clear_msg_list(list);
  903. X        return -1;
  904. X    }
  905. X#else
  906. X    if (err && p)
  907. X        xfree(err);
  908. X    if (p && !(err = regcmp(p, NULL))) {
  909. X        print("regcmp error: %s\n", p);
  910. X        clear_msg_list(list);
  911. X        return -1;
  912. X    }
  913. X#endif SYSV
  914. X    } else if (err == (char *)-1 && mdy[1] <= 0) {
  915. X    print("No previous regular expression\n");
  916. X    clear_msg_list(list);  /* doesn't matter really */
  917. X    return -1;
  918. X    }
  919. X    /* start searching: set bytes, and message number: n */
  920. X    for (n = 0; n < msg_cnt; n++)
  921. X    if (msg_bit(list, n)) {
  922. X        if (mdy[1] > 0) {
  923. X        int msg_mdy[3];
  924. X        if (!(p = msg_date(n))) {
  925. X            unset_msg_bit(list, n);
  926. X            continue; /* error: don't consider this message */
  927. X        }       /* yr mo da */
  928. X        (void) sscanf(p, "%2d%2d%2d",
  929. X             &msg_mdy[2], &msg_mdy[0], &msg_mdy[1]);
  930. X        msg_mdy[0]--;
  931. X        Debug("checking %d's date: %d-%d-%d  ",
  932. X                 n+1, msg_mdy[0]+1, msg_mdy[1], msg_mdy[2]);
  933. X        /* start at year and wrap around.
  934. X         * only when match the day (4), check for == (match)
  935. X         */
  936. X        for (i = 2; i < 5; i++)
  937. X            if (before && msg_mdy[i%3] < mdy[i%3]
  938. X            || !before && msg_mdy[i%3] > mdy[i%3]
  939. X            || i == 4 && (msg_mdy[i%3] == mdy[i%3])) {
  940. X                Debug("matched (%s).\n",
  941. X                (i == 2)? "year" : (i == 3)? "month" : "day");
  942. X                break;
  943. X            } else if (msg_mdy[i%3] != mdy[i%3]) {
  944. X            Debug("failed.\n");
  945. X            unset_msg_bit(list, n);
  946. X            break;
  947. X            }
  948. X        continue;
  949. X        }
  950. X        /* we must have the right date -- if we're searching for a
  951. X         * string, find it.
  952. X         */
  953. X        (void) fseek(tmpf, msg[n].m_offset, L_SET);
  954. X        bytes = 0;
  955. X        while (bytes < msg[n].m_size) {
  956. X        if (!search_subj && !search_from && !search_to &&
  957. X                !(p = fgets(buf, BUFSIZ, tmpf)))
  958. X            break;
  959. X        else if (search_subj) {
  960. X            if (!(p = header_field(n, "subject"))) {
  961. X            unset_msg_bit(list, n);
  962. X            break;
  963. X            }
  964. X        } else if (search_from) {
  965. X            if (!(p = header_field(n, "from"))) {
  966. X            register char *p2;
  967. X            (void) fseek(tmpf, msg[n].m_offset, L_SET);
  968. X            p2 = fgets(buf, BUFSIZ, tmpf);
  969. X            p = index(p2, ' '), p++;
  970. X            if (p2 = any(p, " \t"))
  971. X                *p2 = 0;
  972. X            }
  973. X        } else if (search_to) {
  974. X            if (!(p = header_field(n, "to"))) {
  975. X            unset_msg_bit(list, n);
  976. X            break;
  977. X            }
  978. X        }
  979. X        if (icase)
  980. X            p = lcase_strcpy(buf, p);
  981. X#ifndef SYSV
  982. X        val = re_exec(p);
  983. X#else
  984. X        val = !!regex(err, p, NULL); /* convert value to a boolean */
  985. X#endif SYSV
  986. X        if (val == -1) {   /* doesn't apply in system V */
  987. X            print("Internal error for pattern search.\n");
  988. X            clear_msg_list(list); /* it doesn't matter, really */
  989. X            return -1;
  990. X        }
  991. X        if (xflg)
  992. X            val = !val;
  993. X        if (!val) {
  994. X            /* unset the bit if match failed. If it matches later
  995. X             * in the search, we'll reset to true in the next iteration.
  996. X             * this doesn't apply for author or subject picks.
  997. X             */
  998. X            unset_msg_bit(list, n);
  999. X            bytes += strlen(p);
  1000. X        } else {
  1001. X            set_msg_bit(list, n);
  1002. X            break;
  1003. X        }
  1004. X        if (search_subj || search_from || search_to)
  1005. X            break;
  1006. X        }
  1007. X    }
  1008. X    return 0;
  1009. X}
  1010. X
  1011. X#ifdef CURSES
  1012. X/*
  1013. X * search for a pattern in composed message headers -- also see next function
  1014. X * flags ==  0   forward search (prompt).
  1015. X * flags == -1   continue search (no prompt).
  1016. X * flags ==  1   backward search (prompt).
  1017. X */
  1018. Xsearch(flags)
  1019. Xregister int flags;
  1020. X{
  1021. X    register char   *p;
  1022. X    char           pattern[128];
  1023. X    register int    this_msg = current_msg, val = 0;
  1024. X    static char     *err = (char *)-1, direction;
  1025. X    int            (*oldint)(), (*oldquit)();
  1026. X#ifndef SYSV
  1027. X    char *re_comp();
  1028. X#else SYSV
  1029. X    char *regcmp();
  1030. X#endif SYSV
  1031. X
  1032. X    if (msg_cnt <= 1) {
  1033. X    print("Not enough messages to invoke a search.\n");
  1034. X    return 0;
  1035. X    }
  1036. X    pattern[0] = '\0';
  1037. X    if (flags == -1)
  1038. X    print("continue %s search...", direction? "forward" : "backward");
  1039. X    else
  1040. X    print("%s search: ", flags? "backward" : "forward");
  1041. X    if (flags > -1)
  1042. X    if (Getstr(pattern, COLS-18, 0) < 0)
  1043. X        return 0;
  1044. X    else
  1045. X        direction = !flags;
  1046. X#ifndef SYSV
  1047. X    if (err = re_comp(pattern)) {
  1048. X    print(err);
  1049. X    return 0;
  1050. X    }
  1051. X#else
  1052. X    if (err && *pattern)
  1053. X    xfree(err);
  1054. X    else if (err == (char *)-1 && !*pattern) {
  1055. X    print("No previous regular expression.");
  1056. X    return 0;
  1057. X    }
  1058. X    if (*pattern && !(err = regcmp(pattern, NULL))) {
  1059. X    print("Error in regcmp in %s", pattern);
  1060. X    return 0;
  1061. X    }
  1062. X#endif SYSV
  1063. X    move(LINES-1, 0), refresh();
  1064. X    on_intr();
  1065. X
  1066. X    do  {
  1067. X    if (direction)
  1068. X        current_msg = (current_msg+1) % msg_cnt;
  1069. X    else
  1070. X        if (--current_msg < 0)
  1071. X        current_msg = msg_cnt-1;
  1072. X        p = compose_hdr(current_msg);
  1073. X#ifndef SYSV
  1074. X    val = re_exec(p);
  1075. X#else
  1076. X    val = !!regex(err, p, NULL); /* convert value to a boolean */
  1077. X#endif SYSV
  1078. X    if (val == -1)     /* doesn't apply in system V */
  1079. X        print("Internal error for pattern search.\n");
  1080. X    } while (!val && current_msg != this_msg && isoff(glob_flags, WAS_INTR));
  1081. X
  1082. X    if (ison(glob_flags, WAS_INTR)) {
  1083. X    print("Pattern search interruped.");
  1084. X    current_msg = this_msg;
  1085. X    } else if (val == 0)
  1086. X    print("Pattern not found.");
  1087. X
  1088. X    off_intr();
  1089. X    return val;
  1090. X}
  1091. X#endif CURSES
  1092. X
  1093. X/*
  1094. X * parse a user given date string and set mdy[] array with correct
  1095. X * values.  Return 0 on failure.
  1096. X */
  1097. Xdate1(p)
  1098. Xregister char *p;
  1099. X{
  1100. X    register char *p2;
  1101. X    long      t;
  1102. X    int       i;
  1103. X    struct tm       *today;
  1104. X
  1105. X    if (*p == '-') {
  1106. X    before = 1;
  1107. X    skipspaces(1);
  1108. X    }
  1109. X    if (!isdigit(*p) && *p != '/') {
  1110. X    print("syntax error on date: \"%s\"\n", p);
  1111. X    return 0;
  1112. X    }
  1113. X    (void) time (&t);
  1114. X    today = localtime(&t);
  1115. X    for (i = 0; i < 3; i++)
  1116. X    if (!p || !*p || *p == '/') {
  1117. X        switch(i) {   /* default to today's date */
  1118. X        case 0: mdy[0] = today->tm_mon;
  1119. X        when 1: mdy[1] = today->tm_mday;
  1120. X        when 2: mdy[2] = today->tm_year;
  1121. X        }
  1122. X        if (p && *p)
  1123. X        p++;
  1124. X    } else {
  1125. X        p2 = (*p)? index(p+1, '/') : NULL;
  1126. X        mdy[i] = atoi(p); /* atoi will stop at the '/' */
  1127. X        if (i == 0 && (--(mdy[0]) < 0 || mdy[0] > 11)) {
  1128. X        print("Invalid month: %s\n", p);
  1129. X        return 0;
  1130. X        } else if (i == 1 && (mdy[1] < 1 || mdy[1] > 31)) {
  1131. X        print("Invalid day: %s\n", p);
  1132. X        return 0;
  1133. X        }
  1134. X        if (p = p2) /* set p to p2 and check to see if it's valid */
  1135. X        p++;
  1136. X    }
  1137. X    return 1;
  1138. X}
  1139. END_OF_FILE
  1140. if test 10068 -ne `wc -c <'pick.c'`; then
  1141.     echo shar: \"'pick.c'\" unpacked with wrong size!
  1142. fi
  1143. # end of 'pick.c'
  1144. fi
  1145. if test -f 'setopts.c' -a "${1}" != "-c" ; then 
  1146.   echo shar: Will not clobber existing file \"'setopts.c'\"
  1147. else
  1148. echo shar: Extracting \"'setopts.c'\" \(10254 characters\)
  1149. sed "s/^X//" >'setopts.c' <<'END_OF_FILE'
  1150. X/* setopts.c    (c) copyright 1986 (Dan Heller) */
  1151. X
  1152. X#include "mush.h"
  1153. X
  1154. X/* add an option indicated by "set option[=value]" or by "alias name alias" 
  1155. X * function is recursive, so multilists get appended accordingly
  1156. X */
  1157. Xadd_option(list, argv)
  1158. Xregister struct options **list;
  1159. Xregister char **argv;
  1160. X{
  1161. X    register struct options *tmp;
  1162. X    struct options *calloc();
  1163. X    register char *option, *value = NULL;
  1164. X
  1165. X    if (!(option = *argv))
  1166. X    return 1;
  1167. X    /* check for one of three forms:
  1168. X     * option=value    option = value  option= value
  1169. X     * value can be in quotes to preserve whitespace
  1170. X     */
  1171. X    if (*++argv && !strcmp(*argv, "=")) {
  1172. X    if (value = *++argv) /* example: "set foo = " */
  1173. X        ++argv;
  1174. X    } else if (value = index(option, '=')) {
  1175. X    /* option=value  strip into option="option" value="value"; (quotes?) */
  1176. X    register char c, *p2;
  1177. X    *value = 0; /* option is now a null termined `option' */
  1178. X    if ((c = *++value) == '"' || c == '\'') {
  1179. X        *value++ = 0;
  1180. X        if (!(p2 = index(value, c))) {
  1181. X        print("No matching %c for %s.\n", c, option);
  1182. X        return 0;
  1183. X        } else
  1184. X        *p2 = 0;
  1185. X    } else if (!c) {  /* example: "set crt=" */
  1186. X        if (!*argv) {
  1187. X        print("No value for %s.\n", option);
  1188. X        return 0;
  1189. X        }
  1190. X        value = *argv++;
  1191. X    }
  1192. X    }
  1193. X    /* check to see if option is already set by attempting to unset it */
  1194. X    (void) un_set(list, option);
  1195. X
  1196. X    /* now make a new option struct and set fields */
  1197. X    if (!(tmp = calloc((unsigned)1, sizeof(struct options)))) {
  1198. X    error("calloc");
  1199. X    return -1;
  1200. X    }
  1201. X    tmp->option = savestr(option);
  1202. X    tmp->value = savestr(value); /* strdup handles the NULL case */
  1203. X
  1204. X    tmp->next = *list;
  1205. X    *list = tmp;
  1206. X
  1207. X    /* check for options which must have values or are used frequently */
  1208. X    if (*list == set_options) {
  1209. X#if defined(CURSES) || defined(SUNTOOL)
  1210. X    if (!strcmp(tmp->option, "no_reverse"))
  1211. X        turnoff(glob_flags, REV_VIDEO);
  1212. X    else
  1213. X#endif /* CURSES || SUNTOOL */
  1214. X    if (!strcmp(tmp->option, "prompt"))
  1215. X        prompt = (tmp->value)? tmp->value : DEF_PROMPT;
  1216. X    else if (!strcmp(tmp->option, "escape"))
  1217. X        escape = (tmp->value)? tmp->value : DEF_ESCAPE;
  1218. X    else if (!strcmp(tmp->option, "pager"))
  1219. X        pager = (tmp->value)? tmp->value : DEF_PAGER;
  1220. X    else if (!strcmp(tmp->option, "editor"))
  1221. X        editor = (tmp->value)? tmp->value : DEF_EDITOR;
  1222. X    else if (!strcmp(tmp->option, "hdr_format"))
  1223. X        hdr_format = (tmp->value)? tmp->value : DEF_HDR_FMT;
  1224. X    else if (!strcmp(tmp->option, "visual"))
  1225. X        visual = (tmp->value)? tmp->value : DEF_EDITOR;
  1226. X    else if (!strcmp(tmp->option, "crt")) {
  1227. X        if (!istool)
  1228. X        crt = (tmp->value)? max(atoi(tmp->value), 1): 18;
  1229. X    } else if (!strcmp(tmp->option, "screen")) {
  1230. X        screen = (tmp->value)? max(atoi(tmp->value), 1): 18;
  1231. X#ifdef CURSES
  1232. X        if (iscurses && screen > LINES-2)
  1233. X        screen = LINES-2;
  1234. X#endif CURSES
  1235. X    } else if (!strcmp(tmp->option, "history"))
  1236. X        init_history((value && *value)? atoi(value) : 1);
  1237. X    }
  1238. X
  1239. X    if (*argv)
  1240. X    return add_option(list, argv);
  1241. X    return 1;
  1242. X}
  1243. X
  1244. X/*
  1245. X * If str is NULL, just print options and their values. Note that numerical
  1246. X * values are not converted to int upon return.  If str is not NULL
  1247. X * return the string that matched, else return NULL;
  1248. X */
  1249. Xchar *
  1250. Xdo_set(list, str)
  1251. Xregister struct options *list;
  1252. Xregister char *str;
  1253. X{
  1254. X    register struct options *opts;
  1255. X#ifdef SUNTOOL
  1256. X    int x,y;
  1257. X
  1258. X    if (istool && !str)
  1259. X    y = 10 + 2 * l_height(LARGE);
  1260. X#endif SUNTOOL
  1261. X
  1262. X    for (opts = list; opts; opts = opts->next)
  1263. X    if (!str) {
  1264. X#ifdef SUNTOOL
  1265. X        if (istool)
  1266. X        pw_text(msg_win, 5, y, PIX_SRC, fonts[DEFAULT], opts->option);
  1267. X        else
  1268. X#endif SUNTOOL
  1269. X        fputs(opts->option, stdout);
  1270. X        if (opts->value)
  1271. X#ifdef SUNTOOL
  1272. X        if (istool) {
  1273. X            x = 30*l_width(DEFAULT);
  1274. X            pw_text(msg_win, x,y, PIX_SRC, fonts[DEFAULT], opts->value);
  1275. X            pw_text(msg_win, x+1, y, PIX_SRC|PIX_DST,
  1276. X                 fonts[DEFAULT], opts->value);
  1277. X            x += strlen(opts->value)*l_width(DEFAULT);
  1278. X        } else
  1279. X#endif SUNTOOL
  1280. X            printf("     \t%s", opts->value);
  1281. X#ifdef SUNTOOL
  1282. X        if (istool)
  1283. X        Clrtoeol(msg_win, x, y, DEFAULT), y += l_height(DEFAULT);
  1284. X        else
  1285. X#endif SUNTOOL
  1286. X        putchar('\n');
  1287. X    } else {
  1288. X        if (strcmp(str, opts->option))
  1289. X        continue;
  1290. X        if (opts->value)
  1291. X        return opts->value;
  1292. X        else
  1293. X        return "";
  1294. X    }
  1295. X    /* if we still haven't matched, check for environment vars */
  1296. X    if (str && list == set_options) {
  1297. X    register int N, n;
  1298. X    for (N = 0; environ[N]; N++) {
  1299. X        char *p = index(environ[N], '=');
  1300. X        if (p)
  1301. X        *p = 0;
  1302. X        n = strcmp(str, environ[N]);
  1303. X        if (p)
  1304. X        *p = '=';
  1305. X        if (!n)
  1306. X        return p+1;
  1307. X    }
  1308. X    }
  1309. X    return NULL;
  1310. X}
  1311. X
  1312. X/*
  1313. X * unset the variable described by p in the list "list".
  1314. X * if the variable isn't set, then return 0, else return 1.
  1315. X */
  1316. Xun_set(list, p)
  1317. Xregister struct options **list;
  1318. Xregister char *p;
  1319. X{
  1320. X    register struct options *opts = *list, *tmp;
  1321. X
  1322. X    if (!list || !*list || !p || !*p)
  1323. X    return 0;
  1324. X    if (*list == set_options) {
  1325. X#if defined(CURSES) || defined(SUNTOOL)
  1326. X    if (!strcmp(p, "no_reverse"))
  1327. X        turnon(glob_flags, REV_VIDEO);
  1328. X    else
  1329. X#endif /* CURSES || SUNTOOL */
  1330. X    if (!strcmp(p, "prompt"))
  1331. X        prompt = DEF_PROMPT;
  1332. X    else if (!strcmp(p, "escape"))
  1333. X        escape = DEF_ESCAPE;
  1334. X    else if (!strcmp(p, "pager"))
  1335. X        pager = DEF_PAGER;
  1336. X    else if (!strcmp(p, "editor"))
  1337. X        editor = DEF_EDITOR;
  1338. X    else if (!strcmp(p, "visual"))
  1339. X        visual = DEF_EDITOR;
  1340. X    else if (!strcmp(p, "hdr_format"))
  1341. X        hdr_format = DEF_HDR_FMT;
  1342. X    else if (!strcmp(p, "crt"))
  1343. X        crt = 18;
  1344. X    else if (!strcmp(p, "screen")) {
  1345. X        screen = 18;
  1346. X#ifdef CURSES
  1347. X        if (iscurses && screen > LINES-2)
  1348. X        screen = LINES-2;
  1349. X#endif CURSES
  1350. X    } else if (!strcmp(p, "history"))
  1351. X        init_history(1);
  1352. X    }
  1353. X
  1354. X    if (!strcmp(p, opts->option)) {
  1355. X    *list = (*list)->next;
  1356. X    xfree (opts->option);
  1357. X    if (opts->value)
  1358. X        xfree(opts->value);
  1359. X    xfree((char *)opts);
  1360. X    return 1;
  1361. X    }
  1362. X    for ( ; opts->next; opts = opts->next)
  1363. X    if (!strcmp(p, opts->next->option)) {
  1364. X        tmp = opts->next;
  1365. X        opts->next = opts->next->next;
  1366. X        xfree (tmp->option);
  1367. X        if (tmp->value)
  1368. X        xfree(tmp->value);
  1369. X        xfree ((char *)tmp);
  1370. X        return 1;
  1371. X    }
  1372. X    return 0;
  1373. X}
  1374. X
  1375. X/* The functions below return -1 since they don't affect
  1376. X * messages. This prevents piping from do_loop().
  1377. X */
  1378. Xset(n, argv)
  1379. Xregister int n;
  1380. Xregister char **argv;
  1381. X{
  1382. X    char firstchar = **argv;
  1383. X    register char *cmd = *argv;
  1384. X    register struct options **list;
  1385. X
  1386. X    if (*cmd == 'u')
  1387. X    cmd += 2;
  1388. X    if (*++argv && !strcmp(*argv, "-?"))
  1389. X    return help(0, (*cmd == 'i')? "ignore": "set", cmd_help);
  1390. X    if (*argv && **argv == '?') {
  1391. X    char buf[BUFSIZ];
  1392. X    if (!strcmp(*argv, "?all")) {
  1393. X        FILE *pp = NULL_FILE;
  1394. X        turnon(glob_flags, IGN_SIGS);
  1395. X        echo_on();
  1396. X        if (!istool && !(pp = popen(pager, "w")))
  1397. X        error(pager);
  1398. X        for (n = 0; variable_stuff(n, NULL, buf); n++)
  1399. X        if (pp)
  1400. X            fprintf(pp, "%s\n", buf);
  1401. X        else
  1402. X            print("%s\n", buf);
  1403. X        if (pp)
  1404. X        pclose(pp);
  1405. X        echo_off();
  1406. X        turnoff(glob_flags, IGN_SIGS);
  1407. X    } else {
  1408. X        (void) variable_stuff(0, (*argv)+1, buf);
  1409. X        wprint("%s\n", buf);
  1410. X    }
  1411. X    return -1;
  1412. X    }
  1413. X
  1414. X    if (firstchar == 'u') {
  1415. X    if (!*argv)
  1416. X        print("%s what?\n", cmd);
  1417. X    else {
  1418. X        list = (*cmd == 'i')? &ignore_hdr : &set_options;
  1419. X        do  if (!strcmp(*argv, "*"))
  1420. X            while (*list)
  1421. X            (void) un_set(list, (*list)->option);
  1422. X        else if (!un_set(list, *argv))
  1423. X            print("un%s: %s not set\n",
  1424. X            (*cmd == 'i')? "ignore" : "set", *argv);
  1425. X        while (*++argv);
  1426. X    }
  1427. X    return -1;
  1428. X    }
  1429. X    if (!*argv)
  1430. X    (void) do_set((*cmd == 'i')? ignore_hdr: set_options, NULL);
  1431. X    else
  1432. X    (void) add_option((*cmd == 'i')? &ignore_hdr: &set_options, argv);
  1433. X    return -1;
  1434. X}
  1435. X
  1436. Xalts(argc, argv)
  1437. Xregister char **argv;
  1438. X{
  1439. X    char buf[256], buf2[256], *p;
  1440. X    long save_bang = ison(glob_flags, IGN_BANG);
  1441. X
  1442. X    if (argc && *++argv && !strcmp(*argv, "-?"))
  1443. X    return help(0, "alts_help", cmd_help);
  1444. X    if (argc > 1) {
  1445. X    (void) argv_to_string(buf2, argv);
  1446. X    (void) sprintf(buf, "set alternates=\"%s\"",  buf2);
  1447. X    turnon(glob_flags, IGN_BANG);
  1448. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  1449. X        (void) do_command(argc, argv, msg_list);
  1450. X    if (!save_bang)
  1451. X        turnoff(glob_flags, IGN_BANG);
  1452. X    } else
  1453. X    if (!(p = do_set(set_options, "alternates")))
  1454. X        print("No alternate hostnames set.\n");
  1455. X    else
  1456. X        print("Alternate hostnames: %s\n", p);
  1457. X    return -1;
  1458. X}
  1459. X
  1460. Xsave_opts(cnt, argv)
  1461. Xchar **argv;
  1462. X{
  1463. X    char file[50], *tmp;
  1464. X    register FILE *fp;
  1465. X
  1466. X    if (cnt && *++argv && !strcmp(*argv, "-?"))
  1467. X    return help(0, "source_help", cmd_help);
  1468. X    if (cnt && *argv)
  1469. X    (void) strcpy(file, *argv);
  1470. X    else if (tmp = getenv("MAILRC"))
  1471. X    (void) strcpy(file, tmp);
  1472. X    else {
  1473. X    char *home = do_set(set_options, "home");
  1474. X    if (!home || !*home)
  1475. X        home = ALTERNATE_HOME;
  1476. X    if (access(sprintf(file, "%s/%s", home, MAILRC), R_OK)
  1477. X          && access(sprintf(file, "%s/%s", home, ALTERNATE_RC), R_OK))
  1478. X    (void) strcpy(file, DEFAULT_RC);
  1479. X    }
  1480. X
  1481. X    cnt = 1;
  1482. X    tmp = getpath(file, &cnt);
  1483. X    if (cnt) {
  1484. X    if (cnt == -1)
  1485. X        print("%s: %s\n", file, tmp);
  1486. X    else
  1487. X        print("%s is a directory.\n", tmp);
  1488. X    return -1;
  1489. X    }
  1490. X    if (!(fp = fopen(tmp, "w"))) {
  1491. X    error("Can't open %s", file);
  1492. X    return -1;
  1493. X    }
  1494. X
  1495. X    save_list("basic variable settings", set_options, "set", '=', fp);
  1496. X
  1497. X    save_list("mail headers for outgoing mail", own_hdrs, "my_hdr", 0, fp);
  1498. X
  1499. X    save_list("aliases", aliases, "alias", 0, fp);
  1500. X
  1501. X    save_list("headers to ignore", ignore_hdr, "ignore", ' ', fp);
  1502. X
  1503. X    save_list("command abbreviations", functions, "cmd", ' ', fp);
  1504. X
  1505. X    save_list("command macros for function keys", fkeys, "fkey", ' ', fp);
  1506. X
  1507. X    fclose(fp);
  1508. X    print("All variables and options saved in %s\n", tmp);
  1509. X    return -1;
  1510. X}
  1511. X
  1512. Xsave_list(title, list, command, equals, fp)
  1513. Xstruct options *list;
  1514. Xregister char *command, *title, equals;
  1515. Xregister FILE *fp;
  1516. X{
  1517. X    register struct options *opts;
  1518. X    register char *p;
  1519. X
  1520. X    if (!list)
  1521. X    return;
  1522. X    fprintf(fp, "#\n# %s\n#\n", title);
  1523. X    for (opts = list; opts; opts = opts->next) {
  1524. X    fprintf(fp, "%s %s", command, opts->option);
  1525. X    if (opts->value && *opts->value) {
  1526. X        register char *quote;
  1527. X        if (!equals)
  1528. X        quote = NO_STRING;
  1529. X        else if (p = any(opts->value, "\"'"))
  1530. X        if (*p == '\'') quote = "\"";
  1531. X        else quote = "'";
  1532. X        else
  1533. X        if (!any(opts->value, " \t;|"))
  1534. X            quote = NO_STRING;
  1535. X        else quote = "'";
  1536. X        fputc(equals? equals: ' ', fp);
  1537. X        fprintf(fp, "%s%s%s", quote, opts->value, quote);
  1538. X    }
  1539. X    fputc('\n', fp);
  1540. X    }
  1541. X}
  1542. END_OF_FILE
  1543. if test 10254 -ne `wc -c <'setopts.c'`; then
  1544.     echo shar: \"'setopts.c'\" unpacked with wrong size!
  1545. fi
  1546. # end of 'setopts.c'
  1547. fi
  1548. if test -f 'signals.c' -a "${1}" != "-c" ; then 
  1549.   echo shar: Will not clobber existing file \"'signals.c'\"
  1550. else
  1551. echo shar: Extracting \"'signals.c'\" \(9430 characters\)
  1552. sed "s/^X//" >'signals.c' <<'END_OF_FILE'
  1553. X/* @(#)signals.c    (c) copyright 10/18/86 (Dan Heller) */
  1554. X
  1555. X#include "mush.h"
  1556. X
  1557. X#ifndef SYSV
  1558. Xextern char *sys_siglist[];
  1559. X#else
  1560. X/* sys-v doesn't have normal sys_siglist */
  1561. Xstatic char    *sys_siglist[] = {
  1562. X/* no error */  "no error",
  1563. X/* SIGHUP */    "hangup",
  1564. X/* SIGINT */    "interrupt (rubout)",
  1565. X/* SIGQUIT */    "quit (ASCII FS)",
  1566. X/* SIGILL */    "illegal instruction (not reset when caught)",
  1567. X/* SIGTRAP */    "trace trap (not reset when caught)",
  1568. X/* SIGIOT */    "IOT instruction",
  1569. X/* SIGEMT */    "EMT instruction",
  1570. X/* SIGFPE */    "floating point exception",
  1571. X/* SIGKILL */    "kill (cannot be caught or ignored)",
  1572. X/* SIGBUS */    "bus error",
  1573. X/* SIGSEGV */    "segmentation violation",
  1574. X/* SIGSYS */    "bad argument to system call",
  1575. X/* SIGPIPE */    "write on a pipe with no one to read it",
  1576. X/* SIGALRM */    "alarm clock",
  1577. X/* SIGTERM */    "software termination signal from kill",
  1578. X/* SIGUSR1 */    "user defined signal 1",
  1579. X/* SIGUSR2 */    "user defined signal 2",
  1580. X/* SIGCLD */    "death of a child",
  1581. X/* SIGPWR */    "power-fail restart"
  1582. X};
  1583. X#endif SYSV
  1584. X
  1585. X#ifdef SUNTOOL
  1586. Xmsgwin_handlesigwinch()
  1587. X{
  1588. X    register struct rect rect;
  1589. X    if (exec_pid)
  1590. X    return;
  1591. X    rect = msg_rect;
  1592. X    pw_damaged(msg_win);
  1593. X    /* this prevents old screen from being lost when editor finishes */
  1594. X    if (isoff(glob_flags, IS_GETTING))
  1595. X    gfxsw_interpretesigwinch(msg_sw->ts_data);
  1596. X    gfxsw_handlesigwinch(msg_sw->ts_data);
  1597. X    pw_repairretained(msg_win);
  1598. X    pw_donedamaged(msg_win);
  1599. X    win_getrect(msg_sw->ts_windowfd, &msg_rect);
  1600. X    crt = msg_rect.r_height / l_height(curfont);
  1601. X    if (rect.r_height != msg_rect.r_height || rect.r_width != rect.r_width)
  1602. X    if (getting_opts == 1)
  1603. X        display_opts(0);
  1604. X    else if (getting_opts == 2)
  1605. X        set_fkeys();
  1606. X    else if (msg_pix)
  1607. X        scroll_win(0);
  1608. X}
  1609. X
  1610. Xhdrwin_handlesigwinch()
  1611. X{
  1612. X    register struct rect rect;
  1613. X    rect = hdr_rect;
  1614. X    pw_damaged(hdr_win);
  1615. X    gfxsw_interpretesigwinch(hdr_sw->ts_data);
  1616. X    gfxsw_handlesigwinch(hdr_sw->ts_data);
  1617. X    pw_repairretained(hdr_win);
  1618. X    pw_donedamaged(hdr_win);
  1619. X    win_getrect(hdr_sw->ts_windowfd, &hdr_rect);
  1620. X    if (rect.r_width != hdr_rect.r_width || rect.r_height != hdr_rect.r_height){
  1621. X    pw_writebackground(hdr_win, 0,0,
  1622. X               hdr_rect.r_width, hdr_rect.r_height, PIX_CLR);
  1623. X    screen = hdr_rect.r_height/l_height(DEFAULT);
  1624. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  1625. X    }
  1626. X}
  1627. X
  1628. Xprint_sigwinch()
  1629. X{
  1630. X    pw_damaged(print_win);
  1631. X    gfxsw_handlesigwinch(print_sw->ts_data);
  1632. X    pw_writebackground(print_win, 0,0,
  1633. X        win_getwidth(print_sw->ts_windowfd),
  1634. X    win_getheight(print_sw->ts_windowfd), PIX_CLR);
  1635. X    pw_donedamaged(print_win);
  1636. X    print(NULL);  /* reprint whatever was there before damage */
  1637. X}
  1638. X
  1639. Xsigwinchcatcher()
  1640. X{
  1641. X    tool_sigwinch(tool);
  1642. X}
  1643. X#endif SUNTOOL
  1644. X
  1645. Xinterrupt(sig)
  1646. X{
  1647. X    Debug("interrupt() caught: %d\n", sig);
  1648. X    turnon(glob_flags, WAS_INTR);
  1649. X}
  1650. X
  1651. X/*
  1652. X * catch signals to reset state of the machine.  Always print signal caught.
  1653. X * If signals are ignored, return.  If we're running the shell, longjmp back.
  1654. X */
  1655. X/*ARGSUSED*/
  1656. Xcatch(sig)
  1657. X{
  1658. X    Debug("Caught signal: %d\n", sig);
  1659. X    (void) signal(sig, catch);
  1660. X    if (ison(glob_flags, IGN_SIGS) && sig != SIGTERM && sig != SIGHUP)
  1661. X    return;
  1662. X    print("%s: %s\n", prog_name, sys_siglist[sig]);
  1663. X    turnoff(glob_flags, IS_PIPE);
  1664. X    if (istool || sig == SIGTERM || sig == SIGHUP) {
  1665. X    istool = 1;
  1666. X    (void) setjmp(jmpbuf);
  1667. X    if (ison(glob_flags, IS_GETTING))
  1668. X        rm_edfile(-1);
  1669. X    cleanup(sig);
  1670. X    }
  1671. X    if (ison(glob_flags, DO_SHELL))
  1672. X    longjmp(jmpbuf, 1);
  1673. X}
  1674. X
  1675. X#ifdef SIGCONT
  1676. Xstop_start(sig)
  1677. X{
  1678. X    Debug("Caught signal: %d", sig);
  1679. X    if (sig == SIGCONT) {
  1680. X    (void) signal(SIGTSTP, stop_start);
  1681. X    (void) signal(SIGCONT, stop_start);
  1682. X    if (istool || ison(glob_flags, IGN_SIGS) && !iscurses)
  1683. X        return;
  1684. X    echo_off();
  1685. X    /* we're not in an editor but we're editing a letter */
  1686. X    if (ison(glob_flags, IS_GETTING)) {
  1687. X        if (!exec_pid)
  1688. X        print("(Continue editing letter)\n");
  1689. X    }
  1690. X#ifdef CURSES
  1691. X    else if (iscurses)
  1692. X        if (ison(glob_flags, IGN_SIGS)) {
  1693. X        clr_bot_line();
  1694. X        if (msg_list)
  1695. X            puts(compose_hdr(current_msg));
  1696. X        mail_status(1), addstr("...continue... ");
  1697. X        refresh();
  1698. X        } else {
  1699. X        int curlin = max(1, current_msg - n_array[0] + 1);
  1700. X        redraw();
  1701. X        print("Continue");
  1702. X        move(curlin, 0);
  1703. X        refresh();
  1704. X        /* make sure we lose reverse video on continuation */
  1705. X        if (ison(glob_flags, REV_VIDEO) && msg_cnt) {
  1706. X            char buf[256];
  1707. X            (void) strncpy(buf, compose_hdr(current_msg), COLS-1);
  1708. X            buf[COLS-1] = 0; /* strncpy does not null terminate */
  1709. X            mvaddstr(curlin, 0, buf);
  1710. X        }
  1711. X        }
  1712. X#endif CURSES
  1713. X      else
  1714. X        mail_status(1), fflush(stdout);
  1715. X    } else {
  1716. X#ifdef CURSES
  1717. X    if (iscurses) {
  1718. X        /* when user stops mush, the current header is not in reverse
  1719. X         * video -- note that a refresh() has not been called in curses.c!
  1720. X         * so, make sure that when a continue is called, the reverse video
  1721. X         * for the current message returns.
  1722. X         */
  1723. X        if (isoff(glob_flags, IGN_SIGS) && ison(glob_flags, REV_VIDEO) &&
  1724. X            msg_cnt) {
  1725. X        int curlin = max(1, current_msg - n_array[0] + 1);
  1726. X        char buf[256];
  1727. X        (void) strncpy(buf, stdscr->_y[curlin], COLS-1);
  1728. X        buf[COLS-1] = 0; /* strncpy does not null terminate */
  1729. X        STANDOUT(curlin, 0, buf);
  1730. X        }
  1731. X        print("Stopping...");
  1732. X    }
  1733. X#endif CURSES
  1734. X    echo_on();
  1735. X    (void) signal(SIGTSTP, SIG_DFL);
  1736. X    (void) signal(SIGCONT, stop_start);
  1737. X    (void) kill(getpid(), sig);
  1738. X    }
  1739. X}
  1740. X#endif SIGCONT
  1741. X
  1742. X/*ARGSUSED*/
  1743. Xcleanup(sig)
  1744. X{
  1745. X    char buf[128], c = ison(glob_flags, IGN_SIGS)? 'n' : 'y';
  1746. X
  1747. X#ifdef CURSES
  1748. X    if (iscurses)
  1749. X    iscurses = FALSE, endwin();
  1750. X#endif CURSES
  1751. X
  1752. X    echo_on();
  1753. X
  1754. X    if (ison(glob_flags, IS_GETTING))
  1755. X    turnoff(glob_flags, IS_GETTING), dead_letter();
  1756. X    if ((sig == SIGSEGV || sig == SIGBUS) && isoff(glob_flags, IGN_SIGS)
  1757. X    && *tempfile) {
  1758. X    fprintf(stderr, "remove %s [y]? ", tempfile), fflush(stderr);
  1759. X    if (fgets(buf, 128, stdin))
  1760. X        c = lower(*buf);
  1761. X    }
  1762. X    if (c != 'n' && *tempfile && unlink(tempfile) && !sig && errno != ENOENT)
  1763. X    error(tempfile);
  1764. X#ifdef SUNTOOL
  1765. X    if (istool && tool)
  1766. X    tool_destroy(tool);
  1767. X#endif SUNTOOL
  1768. X    if (sig == SIGSEGV || sig == SIGBUS) {
  1769. X    if (isoff(glob_flags, IGN_SIGS)) {
  1770. X        fprintf(stderr, "coredump [n]? "), fflush(stderr);
  1771. X        if (fgets(buf, 128, stdin))
  1772. X        c = lower(*buf);
  1773. X    }
  1774. X    if (c == 'y')
  1775. X        puts("dumping core for debugging"), abort();
  1776. X    }
  1777. X    exit(sig);
  1778. X}
  1779. X
  1780. X/*
  1781. X * if new mail comes in, print who it's from.  sprintf it all into one
  1782. X * buffer and print that instead of separate print statements to allow
  1783. X * the tool mode to make one print statment. The reason for this is that
  1784. X * when the tool is refreshed (caused by a resize, reopen, move, top, etc)
  1785. X * the last thing printed is displayed -- display the entire line.
  1786. X */
  1787. Xcheck_new_mail()
  1788. X{
  1789. X    int        ret_value;
  1790. X    char        buf[BUFSIZ], buf2[256];
  1791. X    register char  *p = buf;
  1792. X    static long    last_spool_size = -1;
  1793. X
  1794. X#ifdef SUNTOOL
  1795. X    static int is_iconic, was_iconic;
  1796. X
  1797. X    if (istool) {
  1798. X    timerclear(&(mail_timer.it_interval));
  1799. X    timerclear(&(mail_timer.it_value));
  1800. X    mail_timer.it_value.tv_sec = time_out;
  1801. X    setitimer(ITIMER_REAL, &mail_timer, NULL);
  1802. X    }
  1803. X#endif SUNTOOL
  1804. X    /* if fullscreen access in progress (help), don't do anything */
  1805. X    if (ret_value = mail_size()) {
  1806. X#ifdef CURSES
  1807. X    int new_hdrs = last_msg_cnt;
  1808. X#endif CURSES
  1809. X#ifdef SUNTOOL
  1810. X    /* if our status has changed from icon to toolform, then
  1811. X     * there will already be a message stating number of new
  1812. X     * messages.  reset `n' to msg_cnt so we don't restate
  1813. X     * the same # of new messages upon receipt of yet another new message.
  1814. X     */
  1815. X    if (istool && !(is_iconic = (tool->tl_flags&TOOL_ICONIC)) && was_iconic)
  1816. X        last_msg_cnt = msg_cnt;
  1817. X#endif SUNTOOL
  1818. X    turnon(glob_flags, NEW_MAIL);
  1819. X    getmail(); /* msg_cnt gets incremented here */
  1820. X    if (istool) {
  1821. X        mail_status(0);
  1822. X        (void) do_hdrs(0, DUBL_NULL, NULL);
  1823. X    }
  1824. X    p += Strcpy(p, "New mail ");
  1825. X    if (msg_cnt - last_msg_cnt <= 1)
  1826. X        p += strlen(sprintf(p, "(#%d) ", msg_cnt));
  1827. X    else
  1828. X        p += strlen(sprintf(p, "(#%d thru #%d)\n", last_msg_cnt+1,msg_cnt));
  1829. X#ifdef SUNTOOL
  1830. X    /*
  1831. X     * If mush is in tool mode and in icon form, don't update last_msg_cnt
  1832. X     * so that when the tool is opened, print() will print the correct
  1833. X     * number of "new" messages.
  1834. X     */
  1835. X    if (!istool || !(was_iconic = tool->tl_flags & TOOL_ICONIC))
  1836. X#endif SUNTOOL
  1837. X        while (last_msg_cnt < msg_cnt) {
  1838. X        char *p2 = reply_to(last_msg_cnt++, FALSE, buf2);
  1839. X        if (strlen(p2) + (p - buf) >= BUFSIZ-5) {
  1840. X            (void) strcat(p, "...\n");
  1841. X            /* force a loop break by setting last_msg_cnt correctly */
  1842. X            last_msg_cnt = msg_cnt;
  1843. X        } else
  1844. X            p += strlen(sprintf(p, " %s\n", p2));
  1845. X        }
  1846. X#ifdef CURSES
  1847. X    if (iscurses) {
  1848. X        if (strlen(buf) > COLS-1) {
  1849. X        printf("%s --more--", buf), fflush(stdout);
  1850. X        (void) getchar();
  1851. X        (void) clear();
  1852. X        (void) strcpy(buf+COLS-5, " ...");
  1853. X        new_hdrs = n_array[screen-1]; /* force new headers */
  1854. X        }
  1855. X        if (new_hdrs - n_array[screen-1] < screen)
  1856. X        (void) do_hdrs(0, DUBL_NULL, NULL);
  1857. X    }
  1858. X#endif CURSES
  1859. X    print("%s", buf); /* buf might have %'s in them!!! */
  1860. X    } else
  1861. X#ifdef SUNTOOL
  1862. X    if (!istool || !is_iconic)
  1863. X#endif SUNTOOL
  1864. X        turnoff(glob_flags, NEW_MAIL);
  1865. X    if (last_spool_size > -1 && /* handle first case */
  1866. X        !is_spool(mailfile) && last_spool_size < spool_size)
  1867. X    print("You have new mail in your system mailbox.\n"), ret_value = 1;
  1868. X    last_spool_size = spool_size;
  1869. X    return ret_value;
  1870. X}
  1871. X
  1872. X/*ARGSUSED*/   /* we ignore the sigstack, cpu-usage, etc... */
  1873. Xbus_n_seg(sig)
  1874. X{
  1875. X    fprintf(stderr, "%s: %s\n", prog_name,
  1876. X    (sig == SIGSEGV)? "Segmentation violation": "Bus error");
  1877. X    cleanup(sig);
  1878. X}
  1879. END_OF_FILE
  1880. if test 9430 -ne `wc -c <'signals.c'`; then
  1881.     echo shar: \"'signals.c'\" unpacked with wrong size!
  1882. fi
  1883. # end of 'signals.c'
  1884. fi
  1885. echo shar: End of archive 11 \(of 12\).
  1886. cp /dev/null ark11isdone
  1887. MISSING=""
  1888. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1889.     if test ! -f ark${I}isdone ; then
  1890.     MISSING="${MISSING} ${I}"
  1891.     fi
  1892. done
  1893. if test "${MISSING}" = "" ; then
  1894.     echo You have unpacked all 12 archives.
  1895.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1896. else
  1897.     echo You still need to unpack the following archives:
  1898.     echo "        " ${MISSING}
  1899. fi
  1900. ##  End of shell archive.
  1901. exit 0
  1902.